<template>
    <el-select
        :title="title"
        :size="size"
        v-model="selectedVal"
        :collapse-tags="collapseTags"
        :placeholder="placeholder"
        :allow-create="allowCreate"
        :default-first-option="defaultFirstOption"
        :clearable="clearable"
        :multiple="multiple"
        :multiple-limit="multipleLimit"
        :disabled="disabled"
        :filterable="filterable"
        :remote="remote"
        :remote-method="remoteMethod"
        value-key="id">
        <el-option
            v-for="(item,index) in filterOption"
            :name="item.value"
            :label="item.label"
            :value="item.value"
            :disabled="item.disabled"
            :key="'select'+item.value+index">
            <slot v-bind:row="item">
                {{ item.label }}
            </slot>
        </el-option>
    </el-select>
</template>
<script>
import { dictionary } from "@/service/core/dictionary";
import { queryParaCascByIdAndParamType } from '@/service/core/sysConfig';
import { isArray } from "@/utils/Tools";

export default {
    name: "selectPara",
    props: {
        size:{ // 下拉框大小
           type: String,
           default: ""
        },
        code: { // 字典代码
            type: String,
            default: ""
        },
        value: { // v-model绑定值
            type: [String, Array, Number, Boolean],
            default () {
                if (this.multiple) return []
                else return ''
            }
        },
        label: { // label值
            type: [String, Array, Number, Boolean],
            default () {
                if (this.multiple) {
                    return []
                }
                if(!this.multiple) {
                    return ''
                }
            }
        },
        collapseTags: { // 多选时是否将选中值按文字的形式展示
            type: Boolean,
            default: false,
        },
        placeholder: {
            type: String,
            default: '请选择'
        },
        options: { // 外部传入的options 可代替自带的请求项
            type: Array,
            default () {
                return [];
            }
        },
        allowCreate: { // 是否允许创建新条目
            type: Boolean,
            default: false
        },
        defaultFirstOption: { // 按回车键 选择第一项
            type: Boolean,
            default: false
        },
        clearable: { // 选项是否可清除
            type: Boolean,
            default: true
        },
        disabled: { // 是否禁用
            type: Boolean,
            default: false
        },
        multiple: { // 是否多选
            type: Boolean,
            default: false
        },
        multipleLimit: { // 多选时用户最多可以选择的项目数，为 0 则不限制
            type: Number,
            default: 0
        },
        filterable: { // 模糊搜索
            type: Boolean,
            default: true
        },
        remote: { // 远程搜索
            type: Boolean,
            default: false,
        },
        remoteMethod: { // 远程搜索方法
            type: Function,
            default: () => {
                console.error('没有配置远程搜索方法！');
            }
        },
        disabledChange: { // 禁用change事件
            type: Boolean,
            default: false,
        },
        disabledKeys: { // 禁止选择的项的key (即value)
            type: Array,
            default() {
                return []
            }
        },
        casCode: { // 下级级联参数的code
            type: String,
            default: ''
        },
        casVal: { // 下级参数绑定值
            type: [String, Number],
            default: ''
        },
        casLabel: { // 下级参数绑定label
            type: String,
            default: ''
        },
        casOpt: { // 级联参数options
            type: Array,
            default() {
                return []
            }
        },
        clearCasDisabled: { // 是否禁用清空下级级联参数v-model绑定值
            type: Boolean,
            default: false
        },
    },
    data() {
        return {
            selectOption: [],
            visible: false,
            label_tmp: null,
        };
    },
    watch: {
        code(val) {
            if(val) {
                this.getOptions();
            }
        },
        options(val) {
            if(isArray(val)) {
                this.selectOption = [...val];
                this.setDefaultVal(this.selectOption);
            }
        },
        value(val, oldVal) {
            if(!this.valueEquals(val, oldVal)) {
                this.selectChange(val);
            }
        },
    },
    computed: {
        selectedVal: {
            get: function () {
                return this.value
            },
            set: function (val) {
                this.$emit("input", val);
            }
        },
        filterOption() { // 过滤后的下拉项
            if(this.disabledKeys.length > 0) {
                // return this.selectOption.filter(v => this.enable.findIndex(item => item == v.value) > -1);
                return this.selectOption.map(item => {
                    if(this.disabledKeys.findIndex(v => v == item.value) > -1) {
                        return {
                            ...item,
                            disabled: true
                        }
                    }else {
                        return item
                    }
                })
            }
            return this.selectOption;
        },
        title() { // title提示文字
            if(!this.multiple) {
                return this.filterOption.filter(v => v.value == this.value).length == 1 ? this.filterOption.filter(v => v.value == this.value)[0].label : ''
            }else if(this.multiple) {
                return this.filterOption.filter(item => { return this.value.findIndex(v => v == item.value) > -1 }).map(item2 => item2.label);
            }
        },
    },
    mounted() {
        this.$nextTick(() => {
            if (this.code && this.options.length == 0) { // 如果code值不为空且options.lengt==0， 则去请求字典项
                this.getOptions();
            } else { // 否则将外部传入的options显示到下拉框中
                this.selectOption = [...this.options];
                this.setDefaultVal(this.selectOption);
            }
        })
    },
    methods: {
        getOptions() { // 获取字典项
            dictionary(this.code).then(res => {
                if (res.data.code == 1000 && isArray(res.data.data)) {
                    let data = res.data.data;
                    data = data.map(v => {
                        return {
                            ...v,
                            id: v.id,
                            label: v.name,
                            value: v.valStr,
                        };
                    });
                    this.selectOption = [...data];
                    this.setDefaultVal(this.selectOption);
                }
            });
        },
        selectChange(val) { // 选择change事件
            if (this.multiple) { // 多选
                if(isArray(val) && val.length == 0) {
                    this.$emit("update:label", []);
                    this.emitChange([], []);
                    return
                }
                if (isArray(val) && val.length > 0) {
                    this.label_tmp = val.map(v => {
                        let item = this.selectOption.find(n => {
                            return n.value == v;
                        });
                        if(item) {
                            return item.label;
                        }
                    });
                    this.$emit("update:label", this.label_tmp);
                    this.emitChange(val, this.label_tmp)
                }
            }

            if(!this.multiple) { // 单选
                if(!this.valueEquals(val, this.selectedVal)) return
                if(!val) {
                   this.emitChange('', '', '');
                   this.$emit('update:label', '');
                   this.clearCascadeOpt();
                   return
                }
                let total = 0;
                let interval = window.setInterval(() => { // 定时 解决下级级联参数没有触发change事件的问题
                    total++;
                    let obj = this.selectOption.find(v => v.value == val);
                    if (obj) {
                        this.$emit("update:label", obj.label);
                        this.emitChange(this.selectedVal, obj.id, obj.cId);
                        this.getCascadeOption(obj.id);
                        window.clearInterval(interval);
                    }
                    if (total >= 20) { // 超过1秒 结束计数
                        window.clearInterval(interval);
                    }
                }, 100);
            }
        },
        valueEquals(a, b) { // 比较两个值是否相同
            if (a === b) return true;
            if (!(a instanceof Array)) return false;
            if (!(b instanceof Array)) return false;
            if (a.length !== b.length) return false;
            for (let i = 0; i !== a.length; ++i) {
                if (a[i] !== b[i]) return false;
            }
            return true;
        },
        emitChange(...args) { // 触发外部change方法
            if(!this.disabledChange) {
                setTimeout(() => {
                    this.$emit('change', ...args);
                }, 1);
            }
        },
        // 获取下级级联参数的options 开始==================
        getCascadeOption(id) { // 获取下级级联参数
            if(!this.casCode) return
            queryParaCascByIdAndParamType(id, this.casCode).then(res => {
                if(res.data.code == 1000) {
                    let data = res.data.data;
                    if(isArray(data)) {
                        data = data.map(item => {
                            return {
                                value: item.valStr,
                                label: item.name,
                                ...item,
                            }
                        })
                        this.$emit('update:casOpt', data);
                        this.clearCascadeVal();
                    }
                }
            })
        },
        clearCascadeOpt() { // 清空下级级联参数
            if(!this.casCode) return
            this.$emit('update:casOpt', []);
            this.clearCascadeVal();
        },
        clearCascadeVal() { // 清空下级参数绑定值
            if(!this.clearCasDisabled) {
                this.$emit('update:casVal', '');
                this.$emit('update:casLabel', '');
            }
        },
        // 获取下级级联参数的options 结束==================
        setDefaultVal(options=[]) { // 设置默认值(只有值为空的情况下可以设置默认值)
            let def = options.find(v => v.haveDefault == '1');
            if(def) {
                if(!this.multiple) {
                    if(!this.value && this.value !== 0) {
                        this.$emit("input", def.value);
                        this.$emit('update:label', def.label);
                    }
                }else {
                    if(this.value.length == 0) {
                        this.$emit("input", [def.value]);
                        this.$emit('update:label', [def.label]);
                    }
                }
            }
        },
    }
}
</script>
